import { useRef, useState } from 'react'
// 导入 useFormik Hook
import { useFormik } from 'formik'
import * as Yup from 'yup'
// import axios from 'axios' 因为 http 文件中已经使用过了
// 导入 antd-mobile 的样式文件
import { Toast } from 'antd-mobile'
import styles from './index.module.scss'

// 优化前 需要写多次 ../../
// import { http, setToken } from '../../utils/index'
// 优化后：
// import { http, setToken } from '@/utils/index'
import { http, setToken } from '@/utils'

// 导入自定义的 input 组件
// import { Input } from '@/components/Input'
import Input from '@/components/Input'
import NavBar from '@/components/NavBar'
import { useHistory } from 'react-router-dom'

// 修复登录时报错的bug
// 定时器 id  let timerId = -1
const Login = () => {
  // 主动调用 useHistory 来获取 history 对象
  const history = useHistory()
  // 倒计时的时间，单位是秒
  const [time, setTime] = useState(0)
  // 定时器id
  const timerIdRef = useRef(-1)
  // 用来存储手机号码对应的文本框 DOM元素
  // 因为 DOM 元素 获取不到时，默认值为 null, 所以此处给的默认值也为null (跟DOM表现一样)
  const mobileRef = useRef(null)

  // useFormik 的参数是一个对象，也就是配置对象
  const formik = useFormik({
    // 表单项的默认值
    initialValues: {
      mobile: '',
      code: '',
    },

    // 使用 Yup 来进行表单验证
    // Yup.object() 表示对 对象 进行验证，参数是一个对象，表示可以对每个属性进行单独的验证
    // 此处还使用了链式编程
    validationSchema: Yup.object({
      mobile: Yup.string()
        .required('手机号为必填项')
        .matches(/^1[3-9]\d{9}$/, '手机号码格式不正确'),
      code: Yup.string()
        .required('验证码为必填项')
        .matches(/^\d{6}$/, '验证码格式不正确'),
    }),

    // 表单的提交事件：
    // 登录的逻辑代码写在此
    // onSumbit: values => {
    //   console.log('表单项的值', values)
    // },
    onSubmit: async values => {
      // console.log('表单项的值', values)
      try {
        // const res = await axios.post('http://geek.itheima.net/v1_0/authorizations', values)
        const res = await http.post('/authorizations', values)
        console.log('res', res)
        if (res.data.message.toLowerCase() === 'ok') {
          Toast.info('登录成功', 2, () => {
            // console.log('弹窗失败')
            // 登录成功 清理定时器
            clearInterval(timerIdRef.current)
            // 返回首页
            history.push('/home')
            // 保存token
            // localStorage.setItem('geek-app', JSON.stringify(res.data.data))
            setToken(res.data.data)
          })
        }
      } catch (e) {
        // console.log(e)
        // 这里需要 console.dir(e) 才可以
        // Toast.info(res.data.message) // 这里的Toast 为什么不显示呢
        // Toast.info(e.response.message, 2)
        Toast.info(e.response.data.message, 2)
      }
    },
  })

  // 发送请求来获取验证码
  const getCode = async () => {
    // 判断剩余秒数，如果秒数小于0 就允许再次发送
    // 如果秒数 >= 0  就不允许再次发送
    if (time > 0) return

    // 获取手机号码
    const { mobile } = formik.values
    // 手机填写校验 如果不满足以下条件 就返回
    if (!/^1[3-9]\d{9}$/.test(mobile)) {
      // console.log('mobileRef', mobileRef)
      // 手机号对应文本框 DOM 元素

      const mobileInputDOM = mobileRef.current
      // console.log('mipd', mobileInputDOM)
      // focus() 就是获得焦点的一个方法，是DOM 元素自己提供的
      mobileInputDOM.focus()
      //手机号码对应文本框 DOM
      return Toast.info('请输入正确的手机号', 1)
    }

    // 将倒计时时间, 更新为 60s
    setTime(10)
    // 清楚定时器
    clearInterval(timerIdRef.current)
    timerIdRef.current = setInterval(() => {
      console.log(time)
      setTime(time => {
        console.log(time)
        if (time === 1) {
          clearInterval(timerIdRef.current)
        }
        return time - 1
      }, 1000)
    })
    // 手机号码验证成功
    try {
      // 发送请求 获取验证码
      // await axios.get(`http://localhost:8000/v1_0/sms/codes/${mobile}`)
      // await axios.get(`http://geek.itheima.net/v1_0/sms/codes/${mobile}`)
      await http.get(`/sms/codes/${mobile}`)
    } catch (e) {}
  }

  // handleSubmit 处理表单的提交事件
  const {
    handleSubmit,
    handleChange,
    handleBlur,
    values: { mobile, code },
    touched,
    errors,
    // 表示表单验证是否成功
    // 默认值为 true, 一进入页面的值为 true 单纯错误的理解
    // 如果验证成功 isValid 的值为 true, 默认值也为 true
    // 如果验证失败 isValid 的值为 false
    isValid,
  } = formik

  // Object.keys() 用来获取对象中所有的键, 返回值是一个数组
  // 如果得到的数组长度为 0，说明对象中没有属性，也就是 2个表单元素
  // 如果都没有获取过焦点，也就是第一次点击
  // const isFirst = <Object className="keys"></Object>(touched).length ===
  const isFirst = Object.keys(touched).length === 0

  // console.log('isValid', isValid, 'isFirst', isFirst)
  // 一进入页面时 isFirst 的值 是为 false的 isValid 的值 也是 false 的 表示验证失败
  // 第一次点击后 isFirst 的值 为 1 也就是被访问过了也就是

  return (
    <div className={styles.root}>
      {/* 导航栏组件 */}
      {/* <NavBar onClick={onClick} /> */}
      <NavBar onClick={() => history.go(-1)} />

      <h1 className="title">账号登录</h1>

      <div className="login-wrap">
        <form onSubmit={handleSubmit}>
          <div className="form-item">
            {/* 将普通的input 标签元素 换成 Input 的组件 */}
            <Input
              // 注意需要添加 name 属性
              name="mobile"
              value={mobile}
              onChange={handleChange}
              onBlur={handleBlur}
              type="text"
              placeholder="请输入手机号"
              // 将 ref 对象设置为要操作的 DOM 元素 的 ref 属性
              dom={mobileRef}
            />
          </div>
          <div className="error">
            {touched.mobile && errors.mobile ? <div>{errors.mobile}</div> : null}
          </div>
          <div className="form-item">
            <Input
              extra={time <= 0 ? '发送验证码' : `${time}s`}
              onExtraClick={
                //() => { 为了避免报错，先写一个回调函数
                // console.log('extra click') 打印显示信息证明 这个额外的文字点击事件是有效的、
                // 获取验证码
                getCode
              }
              name="code"
              value={code}
              onChange={handleChange}
              onBlur={handleBlur}
              type="text"
              placeholder="请输入验证码"
              className="red"
            />
            {/* 之前在想为啥自己的页面没有出现动态的倒计时，原来这里被自己写死了  */}
            {/*   <span className="code-text" onClick={getCode}>
              发送验证码
            </span> */}
            {/* <span className="code-text" onClick={getCode}>
              {time <= 0 ? '发送验证码' : `${time}s`}
            </span> */}
          </div>
          <div className="error">
            {touched.code && errors.code ? <div>{errors.code}</div> : null}
          </div>
          <div className="form-item">
            {/* isFirst 只在第一次进入页面时 为 true。isValid 只在第一次进入页面时为true 以及表单验证成功时为 true */}
            {/* 判断思路： 
                  1、先判断是不是第一次进入页面，如果是，就不添加 样式
                  2、使用 三元 表达式，再判断是不是验证成功，如果是，就添加 active, 否则，不添加
             */}
            <button
              type="submit"
              disabled={isFirst || !isValid}
              className={isFirst ? '' : isValid ? 'active' : ''}
            >
              登录
            </button>
          </div>
        </form>
      </div>
    </div>
  )
}

export default Login
